package com.xlz.ds;

import java.util.Properties;

import javax.sql.DataSource;

import com.xlz.util.ReflectionUtils;

public class UnpooledDataSourceFactory implements DataSourceFactory {

  private static final String DRIVER_PROPERTY_PREFIX = "driver.";
  private static final int DRIVER_PROPERTY_PREFIX_LENGTH = DRIVER_PROPERTY_PREFIX.length();

  protected DataSource dataSource;

  public UnpooledDataSourceFactory() {
    this.dataSource = new UnpooledDataSource();
  }

  public void setProperties(Properties properties) {
    Properties driverProperties = new Properties();
    for (Object key : properties.keySet()) {
      String propertyName = (String) key;
      if (propertyName.startsWith(DRIVER_PROPERTY_PREFIX)) {
        String value = properties.getProperty(propertyName);
        driverProperties.setProperty(propertyName.substring(DRIVER_PROPERTY_PREFIX_LENGTH), value);
      } else if (ReflectionUtils.hasSetter(dataSource,propertyName)) {
        String value = (String) properties.get(propertyName);
        Object convertedValue = convertValue(dataSource, propertyName, value);
        ReflectionUtils.setFieldValue(dataSource, propertyName, convertedValue);
      } else {
    	  //TODO 
         //throw new DataSourceException("Unknown DataSource property: " + propertyName);
      }
    }
    if (driverProperties.size() > 0) {
    	ReflectionUtils.setFieldValue(dataSource,"driverProperties", driverProperties);
    }
  }

  public DataSource getDataSource() {
    return dataSource;
  }

  private Object convertValue(DataSource dataSource, String propertyName, String value) {
    Object convertedValue = value;
    Class<?> targetType = ReflectionUtils.getDeclaredFieldByObject(dataSource, propertyName).getType();
    if (targetType == Integer.class || targetType == int.class) {
      convertedValue = Integer.valueOf(value);
    } else if (targetType == Long.class || targetType == long.class) {
      convertedValue = Long.valueOf(value);
    } else if (targetType == Boolean.class || targetType == boolean.class) {
      convertedValue = Boolean.valueOf(value);
    }
    return convertedValue;
  }

}
